package com.dude.screens;


import java.util.ArrayList;

import com.dude.R;
import com.dude.interfaces.IMemoryService;
import com.dude.objects.GenericPair;
import com.dude.objects.ImageAndTextArrayAdapter;
import com.dude.utils.DialogsLibrary;
import com.dude.utils.FilesOperations;
import com.dude.utils.FilesOperations.FOException;


import android.os.Bundle;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;

/** this Activity should display to the user all the information about the selected multi object.
 *  it is possible to edit existing profiles / add new profile through it. 
 */
public class ExtendedMultiObject extends Activity {

	//============== global variables =====================
	protected boolean objectHasName=false;
	protected boolean existingProfile = false;	
	protected String name= null;
	protected IMemoryService fo = null;
	protected DialogsLibrary dl = null;
	protected ArrayList<String> commentsList;
	protected ArrayAdapter<String> arrayAdapter;
	protected ArrayList<GenericPair<String, Bitmap>> objectsList = null;
	protected ArrayAdapter<GenericPair<String, Bitmap>> objectsArrayAdapter = null;
		
	
	//=================== widgets==============
	protected TextView objectName;
	protected Button addCommentBtn;
	protected Button deleteBtn;
	protected Button doneBtn;
	protected Button addObjectBtn;
	protected ListView commentsListView;
	protected ListView objectsListView;

	
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);
        setContentView(R.layout.extended_multi_object);
        
        // initialize DialogsLibrary variable
        dl = new DialogsLibrary(ExtendedMultiObject.this, false);       
        // create and check FilesOperation object
        fo = new FilesOperations(this);       
        
        //==================== organize layout of objects' name==================
        objectName = (TextView)findViewById(R.id.objectName);           
        // check if reached this activity from create new profile
        Intent intent = getIntent();        
        boolean isNew = intent.getBooleanExtra(Profiles.isNewProfile, false);
        // if not a new profile, find out the name
        if (!isNew) //showing an existing profile
        {
        	objectHasName=true;
        	existingProfile= true;
        	name = intent.getStringExtra(Profiles.profileName);
        	objectName.setText(name);
        }       
        objectName.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View view) {
				// set up name changing Dialog
				final GenericPair<String, Boolean> gp = new GenericPair<String, Boolean>();
				Dialog dialog = dl.createNameDialog(objectHasName, existingProfile, name, fo, gp);
				dialog.setOnDismissListener(new DialogInterface.OnDismissListener(){
					public void onDismiss(DialogInterface dialog) {
						if (gp.getSecond())
						{
							name = gp.getFirst();
							objectName.setText(gp.getFirst());
							objectHasName = true;
							existingProfile = true;
						}						
					}					
				});				
				dialog.show();
			}      	
        });
        
        //====================organize layout of single objects names and pictures============       
        // show the list of names
        objectsListView = (ListView)findViewById(R.id.multi_object_objects_list);
        if (existingProfile)
        {       	
        	objectsList = fo.getAllIncludedObjects(name);       	      	
        	if (objectsList==null)
        	{
        		dl.createErrorDialog("Uploading the extended profile failed");
        		ExtendedMultiObject.this.finish();
        	}        	
        }
        else 
        	objectsList = new ArrayList<GenericPair<String,Bitmap>>();
        
        objectsArrayAdapter = new ImageAndTextArrayAdapter(ExtendedMultiObject.this, objectsList);       
        objectsListView.setAdapter(objectsArrayAdapter);       
        objectsListView.setOnItemClickListener(new OnItemClickListener(){
    	public void onItemClick(AdapterView<?> parent, View view, int position, long id){				
    			//get the selected picture's name
    	        String objName = objectsList.get(position).getFirst();
    	        Bitmap bitmap = objectsList.get(position).getSecond();
    	        singleObjectDialog(objName, bitmap, position);                       
    		}			 
    	});
        
        // put the object's list in the correct size
        ScreensUtility.setListViewHeightBasedOnChildren(objectsListView);

        // configure button to open dialog that enables capturing a picture
        addObjectBtn = (Button)findViewById(R.id.add_object_button_id);
        addObjectBtn.setOnClickListener(new OnClickListener(){
			public void onClick(View v) {
				// open appropriate dialog box
				if (!existingProfile)
					dl.createOperationDeniedDialog("No Name Was Given For The Object. Please name the object, then try again. ");
				else
					addSingleObjectDialog();
			}           			
    	});

        //==================== organize layout of objects' comments==================       
        commentsListView = (ListView)findViewById(R.id.multi_object_comments_list);
        if (existingProfile){     	
        	commentsList = fo.getAllCommentsForObject(name, false);        	
        	if (commentsList==null){
            	dl.createErrorDialog("Retrieving Comments For Object Failed ");
            	// close the Activity:
            	ExtendedMultiObject.this.finish();
        	}
        }
        else{
        	commentsList = new ArrayList<String>();
        }
        arrayAdapter = new ArrayAdapter<String>(this, R.layout.comments_list_item, commentsList);
        commentsListView.setAdapter(arrayAdapter);
        commentsListView.setOnItemClickListener(new OnItemClickListener(){
			 public void onItemClick(AdapterView<?> parent, View view, int position, long id){	
				 //get the selected item
	             String comment = ((TextView) view).getText().toString();	             
	             //Launching Dialog on selecting single List Item
	             dl.editCommentDialog(name, fo, commentsList, arrayAdapter, comment, position, commentsListView);            
			 }			 
		 });       
        ScreensUtility.setListViewHeightBasedOnChildren(commentsListView);
               
        addCommentBtn = (Button)findViewById(R.id.multi_object_add_comment_button_id);
        addCommentBtn.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View view) {
				// set up name changing Dialog
		    	if (!objectHasName)
		    		dl.createOperationDeniedDialog("No Name Was Given For The Object. Please name the object, then try again. ");
		    	else
		    		 dl.AddCommentDialog(name, fo, commentsList, arrayAdapter, commentsListView);	
			}      	
        });
        
        
        //==================== set listeners to buttons================== 
    	deleteBtn = (Button)findViewById(R.id.delete_multi_object_button_id);
    	deleteBtn.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View view) {
				dl.deleteObjectDialog(name, fo);
			}      	
        });
    	doneBtn = (Button)findViewById(R.id.done_multi_object_button_id);
    	doneBtn.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View view) {
				// go back to previous screen
				ExtendedMultiObject.this.finish();
			}      	
        });

    	
    }

   
  
    
    /* this method opens a dialog that displays options regarding a single object 
     * contained in the multi object
     */
    protected void singleObjectDialog(final String objName, Bitmap bitmap, final int posInList)
    {
    	//create the dialog
    	final Dialog dialog = new Dialog(ExtendedMultiObject.this);    	
    	dialog.setContentView(R.layout.single_object_layout);
		dialog.setTitle("The Single Object");
		dialog.setCancelable(true);
		
        // insert actual details about the object
        TextView nameTV = (TextView)dialog.findViewById(R.id.nameTV);
        nameTV.setText(objName);       
        ImageView img = (ImageView)dialog.findViewById(R.id.objects_image_id);
        img.setImageBitmap(bitmap);
        
        // add listeners to the buttons	
		Button deleteButton = (Button)dialog.findViewById(R.id.delete_object_button);
		Button showButton = (Button)dialog.findViewById(R.id.extend_profile_button);;
		Button cancelButton = (Button)dialog.findViewById(R.id.cancelButton);		
		deleteButton.setOnClickListener(new OnClickListener(){
				public void onClick(View v) {
					if (!fo.removeObjectFromMultiObject(name, objName))
					{
						dl.createErrorDialog("Operation [Remove An Object From The Multi Object Failed]");
						dialog.dismiss();
						return;
					}
					else
					{
						objectsList.remove(posInList);						
						objectsArrayAdapter.notifyDataSetChanged();
						dialog.dismiss();
						return;
					}
				}				
		 });
		
		showButton.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				// open the extended profile of the object
				Intent i = new Intent(ExtendedMultiObject.this, ExtendedSingleProfile.class);
	            i.putExtra(Profiles.profileName, objName);
	            i.putExtra(Profiles.isNewProfile, false);
	            startActivity(i);	
				dialog.dismiss();						
			}				
	 });
					
		cancelButton.setOnClickListener(new OnClickListener(){
				@Override
				public void onClick(View v) {
					dialog.dismiss();						
				}				
		 });
		 
    	dialog.show();   
    }
    
   
    
    /* the method displays a dialog through which the user can choose a single object to include
     * in the multi object
     */
    protected void addSingleObjectDialog()
    {
		// get all multi objects' names
		final String [] names = fo.getOneTypeObjectsNames(false);
		if (names==null)
		{
			dl.createErrorDialog("Operation [Add Objects to Multi Object Failed]");
			return;
		}
		// if no single objects exist yet, abort here
		if (names.length==0)
		{
			dl.createOperationDeniedDialog("There are no Objects in the system");
			return;
		}
		
    	//create the dialog
		AlertDialog.Builder builder = new AlertDialog.Builder(this); 
		builder.setTitle("Choose the objects you wish to include in your multi-object in:");
		builder.setCancelable(true);
					
		// an array to keep track of which multi-objects were chosen
		final boolean [] chosen = new boolean[names.length];
		for (int i=0; i<chosen.length; ++i)
			if (isObjectInMulti(names[i]))
				chosen[i] = true;
			else
				chosen[i] = false;
			
		// set the items to be chosen from
		builder.setMultiChoiceItems(names, chosen, new DialogInterface.OnMultiChoiceClickListener(){
			public void onClick(DialogInterface dialog, int which, boolean isChecked) {
				if (isChecked)
					chosen[which] = true;
				else
					chosen[which] = false;				
			}			
		});
		//set buttons
		builder.setPositiveButton("Save", new DialogInterface.OnClickListener(){
			public void onClick(DialogInterface dialog, int which) {
				boolean needToRefreshDisplay = false;
				for (int i=0; i<chosen.length; ++i)
				{
					if (chosen[i])
					{
						// don't add an object that's already in multi object
						if (isObjectInMulti(names[i]))
							continue;
						// need to add a new object
						needToRefreshDisplay = true;
						// if the object wasn't in the multi object before - add it
						if (!fo.addObjectToMultiObject(name, names[i]))
						{
							dl.createErrorDialog("Operation [Add Object to Multi Object Failed]");
							dialog.dismiss();
							return;
						}
						// update the list of objects in the multi's profile
						GenericPair<String, Bitmap> gp = null;
						try {
							gp = fo.getProfileImage(names[i], true);
						} catch (FOException e) {
							dl.createErrorDialog("Updating list of objects failed");
							return;
						}
						if (gp!=null) // the newly added object has a picture						
							objectsList.add(new GenericPair<String, Bitmap>(names[i], gp.getSecond()));						
						else
							objectsList.add(new GenericPair<String, Bitmap>(names[i], null));
					}
					else
					{
						// if the object wasn't in the multi object before - do nothing
						if (!isObjectInMulti(names[i]))
							continue;
						// need to remove the object 
						needToRefreshDisplay = true;
						if (!fo.removeObjectFromMultiObject(name, names[i]))
						{
							dl.createErrorDialog("Operation [Add Object to Multi Object Failed]");
							dialog.dismiss();
							return;
						}
						// update the list of objects in the multi's profile
						int index=-1;
						for (int j=0; j<objectsList.size(); ++j)
						{
							if (objectsList.get(j).getFirst().equals(names[i]))
							{
								index=j;
								break;
							}							
						}
						if (index!=-1)
							objectsList.remove(index);
					}
				}	
				if (needToRefreshDisplay)
				{
					objectsArrayAdapter.notifyDataSetChanged();
				    ScreensUtility.setListViewHeightBasedOnChildren(objectsListView);
				}
				dialog.dismiss();				
			}			
		});
		builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}			
		});
		AlertDialog dialog = builder.create();
		dialog.show();   	
    }
    
    
    /* the method returns true if an object by name objName is already included in the
     *  current multi object (i.e. it's name appears in objectsList). else it returns false.
     */
    protected boolean isObjectInMulti(String objName)
    {
		for (GenericPair<String, Bitmap> gp : objectsList)
			if (gp.getFirst().equals(objName))
				return true;
		return false;
    }

    
}
